#include "my_stdio.h"

#ifdef DEBUG 

#include <stdio.h>

#endif 


FILE_* fopen_(const char* file_name, const char* mode)
{
     int flags = 0;
     int open_mode = 0666;
     if (strcmp(mode, "r") == 0)
     {
         flags |= O_RDONLY;
     }
     else if (strcmp(mode, "w") == 0)
     {
         flags |= (O_WRONLY | O_CREAT | O_TRUNC);
     }
     else if (strcmp(mode, "a") == 0)
     { 
         flags |= (O_WRONLY | O_CREAT | O_APPEND);
     }
     else 
     {
         //...
     }

    int fd = 0;
    if (flags & O_RDONLY)
        fd = open(file_name, flags);
    else 
        fd = open(file_name, flags, open_mode);

    if (fd < 0)
    {
        const char* err = strerror(errno);
        write(2, err, strlen(err));
        return NULL;
    }

    FILE_* fp = (FILE_*)malloc(sizeof(FILE_));
    assert(fp);

    fp->_flags = SYNC_LINE;
    fp->_fileno = fd;
    fp->_size = 0;
    memset(fp->_buffer, 0, BUFFER_SIZE);
    return fp;
}

void fwrite_(const void* ptr, size_t size, FILE_* fp)
{
    memcpy(fp->_buffer+fp->_size, ptr, size);
    fp->_size += size;

    if (fp->_flags & SYNC_NOW)
    {

#ifdef DEBUG 
        printf("fwrite_ SYNC_NOW\n");
#endif

        write(fp->_fileno, fp->_buffer, fp->_size);
        fp->_size = 0;
    }
    else if (fp->_flags & SYNC_LINE)
    {

#ifdef DEBUG 
        printf("fwrite_ SYNC_LINE\n");
#endif
        if (fp->_buffer[fp->_size-1] == '\n')
        {

#ifdef DEBUG 
        printf("fwrite_ SYNC_NOW_2    _fileno : %d \n", fp->_fileno);
#endif
            if (write(fp->_fileno, fp->_buffer, fp->_size) < 0)
            {
#ifdef DEBUG 
                printf("write error\n");
#endif
            }
            fp->_size = 0;
        }
    }
    else if (fp->_flags & SYNC_FULL)
    {

#ifdef DEBUG 
        printf("fwrite_ SYNC_FULL\n");
#endif
        if (fp->_size == BUFFER_SIZE)
        {
            write(fp->_fileno, fp->_buffer, fp->_size);
            fp->_size = 0;
        }
    }
    else 
    {

#ifdef DEBUG 
        printf("fwrite_  else\n");
#endif
        //...
    }


}

void fflush_(FILE_* fp)
{
    if (fp->_size > 0)
        write(fp->_fileno, fp->_buffer, fp->_size);
    else 
        fsync(fp->_fileno);

    fp->_size = 0;
}

void fclose_(FILE_* fp)
{
    fflush_(fp);
    close(fp->_fileno);
} 
